<!-- HTML header for doxygen 1.8.6-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<title>OpenCV: Image Thresholding</title>
<link href="../../opencv.ico" rel="shortcut icon" type="image/x-icon" />
<link href="../../tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../jquery.js"></script>
<script type="text/javascript" src="../../dynsections.js"></script>
<script type="text/javascript" src="../../tutorial-utils.js"></script>
<link href="../../search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../search/searchdata.js"></script>
<script type="text/javascript" src="../../search/search.js"></script>
<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    extensions: ["tex2jax.js", "TeX/AMSmath.js", "TeX/AMSsymbols.js"],
    jax: ["input/TeX","output/HTML-CSS"],
});
//<![CDATA[
MathJax.Hub.Config(
{
  TeX: {
      Macros: {
          matTT: [ "\\[ \\left|\\begin{array}{ccc} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{array}\\right| \\]", 9],
          fork: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ \\end{array} \\right.", 4],
          forkthree: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ \\end{array} \\right.", 6],
          forkfour: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ #7 & \\mbox{#8}\\\\ \\end{array} \\right.", 8],
          vecthree: ["\\begin{bmatrix} #1\\\\ #2\\\\ #3 \\end{bmatrix}", 3],
          vecthreethree: ["\\begin{bmatrix} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{bmatrix}", 9],
          cameramatrix: ["#1 = \\begin{bmatrix} f_x & 0 & c_x\\\\ 0 & f_y & c_y\\\\ 0 & 0 & 1 \\end{bmatrix}", 1],
          distcoeffs: ["(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \\tau_x, \\tau_y]]]]) \\text{ of 4, 5, 8, 12 or 14 elements}"],
          distcoeffsfisheye: ["(k_1, k_2, k_3, k_4)"],
          hdotsfor: ["\\dots", 1],
          mathbbm: ["\\mathbb{#1}", 1],
          bordermatrix: ["\\matrix{#1}", 1]
      }
  }
}
);
//]]>
</script><script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js"></script>
<link href="../../doxygen.css" rel="stylesheet" type="text/css" />
<link href="../../stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<!--#include virtual="/google-search.html"-->
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectlogo"><img alt="Logo" src="../../opencv-logo-small.png"/></td>
  <td style="padding-left: 0.5em;">
   <div id="projectname">OpenCV
   &#160;<span id="projectnumber">4.5.2</span>
   </div>
   <div id="projectbrief">Open Source Computer Vision</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "../../search",false,'Search');
</script>
<script type="text/javascript" src="../../menudata.js"></script>
<script type="text/javascript" src="../../menu.js"></script>
<script type="text/javascript">
$(function() {
  initMenu('../../',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="../../d5/d10/tutorial_js_root.html">OpenCV.js Tutorials</a></li><li class="navelem"><a class="el" href="../../d2/df0/tutorial_js_table_of_contents_imgproc.html">Image Processing</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">Image Thresholding </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><h2>Goal </h2>
<ul>
<li>In this tutorial, you will learn Simple thresholding, Adaptive thresholding, Otsu's thresholding etc.</li>
<li>You will learn these functions : <b><a class="el" href="../../d7/d1b/group__imgproc__misc.html#gae8a4a146d1ca78c626a53577199e9c57" title="Applies a fixed-level threshold to each array element. ">cv.threshold</a></b>, <b><a class="el" href="../../d7/d1b/group__imgproc__misc.html#ga72b913f352e4a1b1b397736707afcde3" title="Applies an adaptive threshold to an array. ">cv.adaptiveThreshold</a></b> etc.</li>
</ul>
<h2>Simple Thresholding </h2>
<p>Here, the matter is straight forward. If pixel value is greater than a threshold value, it is assigned one value (may be white), else it is assigned another value (may be black).</p>
<p>We use the function: <b><a class="el" href="../../d7/d1b/group__imgproc__misc.html#gae8a4a146d1ca78c626a53577199e9c57" title="Applies a fixed-level threshold to each array element. ">cv.threshold</a> (src, dst, thresh, maxval, type)</b> </p><dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">src</td><td>input array. </td></tr>
    <tr><td class="paramname">dst</td><td>output array of the same size and type and the same number of channels as src. </td></tr>
    <tr><td class="paramname">thresh</td><td>threshold value. </td></tr>
    <tr><td class="paramname">maxval</td><td>maximum value to use with the <a class="el" href="../../d7/d1b/group__imgproc__misc.html#ggaa9e58d2860d4afa658ef70a9b1115576a147222a96556ebc1d948b372bcd7ac59" title=" ">cv.THRESH_BINARY</a> and <a class="el" href="../../d7/d1b/group__imgproc__misc.html#ggaa9e58d2860d4afa658ef70a9b1115576a19120b1a11d8067576cc24f4d2f03754" title=" ">cv.THRESH_BINARY_INV</a> thresholding types. </td></tr>
    <tr><td class="paramname">type</td><td>thresholding type(see <a class="el" href="../../d7/d1b/group__imgproc__misc.html#gaa9e58d2860d4afa658ef70a9b1115576">cv.ThresholdTypes</a>).</td></tr>
  </table>
  </dd>
</dl>
<p><b>thresholding type</b> - OpenCV provides different styles of thresholding and it is decided by the fourth parameter of the function. Different types are:</p>
<ul>
<li><a class="el" href="../../d7/d1b/group__imgproc__misc.html#ggaa9e58d2860d4afa658ef70a9b1115576a147222a96556ebc1d948b372bcd7ac59" title=" ">cv.THRESH_BINARY</a></li>
<li><a class="el" href="../../d7/d1b/group__imgproc__misc.html#ggaa9e58d2860d4afa658ef70a9b1115576a19120b1a11d8067576cc24f4d2f03754" title=" ">cv.THRESH_BINARY_INV</a></li>
<li><a class="el" href="../../d7/d1b/group__imgproc__misc.html#ggaa9e58d2860d4afa658ef70a9b1115576ac7e89a5e95490116e7d2082b3096b2b8" title=" ">cv.THRESH_TRUNC</a></li>
<li><a class="el" href="../../d7/d1b/group__imgproc__misc.html#ggaa9e58d2860d4afa658ef70a9b1115576a0e50a338a4b711a8c48f06a6b105dd98" title=" ">cv.THRESH_TOZERO</a></li>
<li><a class="el" href="../../d7/d1b/group__imgproc__misc.html#ggaa9e58d2860d4afa658ef70a9b1115576a95251923e8e22f368ffa86ba8bce87ff" title="flag, use Otsu algorithm to choose the optimal threshold value ">cv.THRESH_OTSU</a></li>
<li><a class="el" href="../../d7/d1b/group__imgproc__misc.html#ggaa9e58d2860d4afa658ef70a9b1115576a22ffcf680811aed95be6c7f5cd809621" title="flag, use Triangle algorithm to choose the optimal threshold value ">cv.THRESH_TRIANGLE</a></li>
</ul>
<dl class="section note"><dt>Note</dt><dd>Input image should be single channel only in case of <a class="el" href="../../d7/d1b/group__imgproc__misc.html#ggaa9e58d2860d4afa658ef70a9b1115576a95251923e8e22f368ffa86ba8bce87ff" title="flag, use Otsu algorithm to choose the optimal threshold value ">cv.THRESH_OTSU</a> or <a class="el" href="../../d7/d1b/group__imgproc__misc.html#ggaa9e58d2860d4afa658ef70a9b1115576a22ffcf680811aed95be6c7f5cd809621" title="flag, use Triangle algorithm to choose the optimal threshold value ">cv.THRESH_TRIANGLE</a> flags</dd></dl>
<h2>Try it </h2>
<p> 
<iframe src="../../js_thresholding_threshold.html" width="100%"
        onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
</iframe>
</p>
<h2>Adaptive Thresholding </h2>
<p>In the previous section, we used a global value as threshold value. But it may not be good in all the conditions where image has different lighting conditions in different areas. In that case, we go for adaptive thresholding. In this, the algorithm calculate the threshold for a small regions of the image. So we get different thresholds for different regions of the same image and it gives us better results for images with varying illumination.</p>
<p>We use the function: <b><a class="el" href="../../d7/d1b/group__imgproc__misc.html#ga72b913f352e4a1b1b397736707afcde3" title="Applies an adaptive threshold to an array. ">cv.adaptiveThreshold</a> (src, dst, maxValue, adaptiveMethod, thresholdType, blockSize, C)</b> </p><dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">src</td><td>source 8-bit single-channel image. </td></tr>
    <tr><td class="paramname">dst</td><td>destination image of the same size and the same type as src. </td></tr>
    <tr><td class="paramname">maxValue</td><td>non-zero value assigned to the pixels for which the condition is satisfied </td></tr>
    <tr><td class="paramname">adaptiveMethod</td><td>adaptive thresholding algorithm to use. </td></tr>
    <tr><td class="paramname">thresholdType</td><td>thresholding type that must be either <a class="el" href="../../d7/d1b/group__imgproc__misc.html#ggaa9e58d2860d4afa658ef70a9b1115576a147222a96556ebc1d948b372bcd7ac59" title=" ">cv.THRESH_BINARY</a> or <a class="el" href="../../d7/d1b/group__imgproc__misc.html#ggaa9e58d2860d4afa658ef70a9b1115576a19120b1a11d8067576cc24f4d2f03754" title=" ">cv.THRESH_BINARY_INV</a>. </td></tr>
    <tr><td class="paramname">blockSize</td><td>size of a pixel neighborhood that is used to calculate a threshold value for the pixel: 3, 5, 7, and so on. </td></tr>
    <tr><td class="paramname">C</td><td>constant subtracted from the mean or weighted mean (see the details below). Normally, it is positive but may be zero or negative as well.</td></tr>
  </table>
  </dd>
</dl>
<p><b>adaptiveMethod</b> - It decides how thresholding value is calculated:</p><ul>
<li><a class="el" href="../../d7/d1b/group__imgproc__misc.html#ggaa42a3e6ef26247da787bf34030ed772cad0c5199ae8637a6b195062fea4789fa9">cv.ADAPTIVE_THRESH_MEAN_C</a></li>
<li><a class="el" href="../../d7/d1b/group__imgproc__misc.html#ggaa42a3e6ef26247da787bf34030ed772caf262a01e7a3f112bbab4e8d8e28182dd">cv.ADAPTIVE_THRESH_GAUSSIAN_C</a></li>
</ul>
<h2>Try it </h2>
<p> 
<iframe src="../../js_thresholding_adaptiveThreshold.html" width="100%"
        onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
</iframe>
 </p>
</div></div><!-- contents -->
<!-- HTML footer for doxygen 1.8.6-->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Fri Apr 2 2021 11:36:37 for OpenCV by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="../../doxygen.png" alt="doxygen"/>
</a> 1.8.13
</small></address>
<script type="text/javascript">
//<![CDATA[
addTutorialsButtons();
//]]>
</script>
</body>
</html>
